home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / tnos / tnos100s / pathname.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-30  |  3.6 KB  |  147 lines

  1. /* Convert relative to absolute pathnames
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4. #include <stdio.h>
  5. #include "global.h"
  6. #include "dirutil.h"
  7. #include "config.h"
  8. #ifdef CALLSERVER
  9. #include <string.h>
  10. extern char *CDROM; /* buckbook.c: defines CDROM drive letter e.g. "s:"  */
  11. #endif
  12.  
  13. void crunch __ARGS((char *buf,char *path));
  14. extern char *skipwhite __ARGS((char *str));
  15.  
  16. /* Given a working directory and an arbitrary pathname, resolve them into
  17.  * an absolute pathname. Memory is allocated for the result, which
  18.  * the caller must free
  19.  */
  20. char *
  21. pathname(cd,path)
  22. char *cd;    /* Current working directory */
  23. char *path;    /* Pathname argument */
  24. {
  25.     register char *buf;
  26. #ifdef    MSDOS
  27.     char *cp,c;
  28.     char *tbuf;
  29.     int tflag = 0;
  30. #endif
  31. #ifdef CALLSERVER
  32.   int drive = 0;  /* is there a drive spec to preserve? */
  33. #endif
  34.  
  35.     if(cd == NULLCHAR || path == NULLCHAR)
  36.         return NULLCHAR;
  37.  
  38. #ifdef    MSDOS
  39.     /* If path has any backslashes, make a local copy with them
  40.      * translated into forward slashes
  41.      */
  42.     if(strchr(path,'\\') != NULLCHAR){
  43.         tflag = 1;
  44.         cp = tbuf = strdup(path);
  45.         while((c = *path++) != '\0'){
  46.             if(c == '\\')
  47.                 *cp++ = '/';
  48.             else
  49.                 *cp++ = c;
  50.         }
  51.         *cp = '\0';
  52.         path = tbuf;
  53.     }
  54. #endif
  55.  
  56.     /* Strip any leading white space on args */
  57.     cd = skipwhite (cd);
  58.     path = skipwhite (path);
  59.  
  60. #ifdef CALLSERVER
  61.   if (CDROM != NULLCHAR && strncmp(path, CDROM, 2) == 0)  {
  62.     buf = strdup(path);
  63.     return buf;
  64.   }
  65.   if (CDROM != NULLCHAR &&  strncmp(cd, CDROM, 2) == 0) drive = 1;
  66.                                                             /* make a note  */
  67. #endif
  68.     /* Allocate and initialize output buffer; user must free */
  69.     buf = mallocw((unsigned)strlen(cd) + strlen(path) + 10);    /* fudge factor */
  70.     buf[0] = '\0';
  71.  
  72.     /* Interpret path relative to cd only if it doesn't begin with "/" */
  73.     if(path[0] != '/')
  74.         crunch(buf,cd);
  75.  
  76. #ifdef CALLSERVER
  77.   else (drive = 0);
  78. #endif
  79.     crunch(buf,path);
  80.  
  81.     /* Special case: null final path means the root directory */
  82.     if(buf[0] == '\0'){
  83.         buf[0] = '/';
  84.         buf[1] = '\0';
  85.     }
  86. #ifdef    MSDOS
  87.     if(tflag)
  88.         free(tbuf);
  89. #endif
  90. #ifdef CALLSERVER
  91.   if (drive)  {
  92.     cp = buf;
  93.     while (*cp != '\0') *cp = *(cp++ + 1);
  94.   }
  95. #endif
  96.     return buf;
  97. }
  98.  
  99. /* Process a path name string, starting with and adding to
  100.  * the existing buffer
  101.  */
  102. void
  103. crunch(buf,path)
  104. char *buf;
  105. register char *path;
  106. {
  107.     register char *cp;
  108.     
  109.  
  110.     cp = buf + strlen(buf);    /* Start write at end of current buffer */
  111.     
  112.     /* Now start crunching the pathname argument */
  113.     for(;;){
  114.         /* Strip leading /'s; one will be written later */
  115.         while(*path == '/')
  116.             path++;
  117.         if(*path == '\0')
  118.             break;        /* no more, all done */
  119.         /* Look for parent directory references, either at the end
  120.          * of the path or imbedded in it
  121.          */
  122.         if(strcmp(path,"..") == 0 || strncmp(path,"../",3) == 0){
  123.             /* Hop up a level */
  124.             if((cp = strrchr(buf,'/')) == NULLCHAR)
  125.                 cp = buf;    /* Don't back up beyond root */
  126.             *cp = '\0';        /* In case there's another .. */
  127.             path += 2;        /* Skip ".." */
  128.             while(*path == '/')    /* Skip one or more slashes */
  129.                 path++;
  130.         /* Look for current directory references, either at the end
  131.          * of the path or imbedded in it
  132.          */
  133.         } else if(strcmp(path,".") == 0 || strncmp(path,"./",2) == 0){
  134.             /* "no op" */
  135.             path++;            /* Skip "." */
  136.             while(*path == '/')    /* Skip one or more slashes */
  137.                 path++;
  138.         } else {
  139.             /* Ordinary name, copy up to next '/' or end of path */
  140.             *cp++ = '/';
  141.             while(*path != '/' && *path != '\0')
  142.                 *cp++ = *path++;
  143.         }
  144.     }
  145.     *cp++ = '\0';
  146. }
  147.